});
notification.connect('destroy', () => this._notifications.delete(mount));
this._notifications.set(mount, notification);
- source.showNotification(notification);
+ source.addNotification(notification);
}
addMount(mount, apps, contentTypes) {
delete this._notifications[requestId];
});
- source.showNotification(notification);
+ source.addNotification(notification);
}
_newRequest(agent, requestId, connection, settingName, hints, flags) {
_('Extension updates are ready to be installed.'));
notification.connect('activated',
() => source.open());
- source.showNotification(notification);
+ source.addNotification(notification);
}
}
notification.addAction(_('Undo'),
() => (global.context.unsafe_mode = false));
notification.setTransient(true);
- source.showNotification(notification);
+ source.addNotification(notification);
});
// Provide the bus object for gnome-session to
const source = MessageTray.getSystemSource();
let notification = new MessageTray.Notification(source, msg, details);
notification.setTransient(true);
- source.showNotification(notification);
+ source.addNotification(notification);
}
/**
'destroy': {param_types: [GObject.TYPE_UINT]},
'notification-added': {param_types: [Notification.$gtype]},
'notification-removed': {param_types: [Notification.$gtype]},
- 'notification-show': {param_types: [Notification.$gtype]},
+ 'notification-request-banner': {param_types: [Notification.$gtype]},
},
}, class Source extends MessageList.Source {
constructor(params) {
this.destroy();
}
- pushNotification(notification) {
+ addNotification(notification) {
if (this.notifications.includes(notification))
return;
this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED);
notification.connect('destroy', this._onNotificationDestroy.bind(this));
- notification.connect('notify::acknowledged', this.countUpdated.bind(this));
- this.notifications.push(notification);
- this.emit('notification-added', notification);
-
- this.countUpdated();
- }
+ notification.connect('notify::acknowledged', () => {
+ this.countUpdated();
- showNotification(notification) {
- notification.acknowledged = false;
- this.pushNotification(notification);
-
- if (notification.urgency === Urgency.LOW)
- return;
+ // If acknowledged was set to false try to show the notification again
+ if (!notification.acknowledged)
+ this.emit('notification-request-banner', notification);
+ });
+ this.notifications.push(notification);
- if (this.policy.showBanners || notification.urgency === Urgency.CRITICAL)
- this.emit('notification-show', notification);
+ this.emit('notification-added', notification);
+ this.emit('notification-request-banner', notification);
}
destroy(reason) {
this._sources.add(source);
source.connectObject(
- 'notification-show', this._onNotificationShow.bind(this),
+ 'notification-request-banner', this._onNotificationRequestBanner.bind(this),
'notification-removed', this._onNotificationRemoved.bind(this),
'destroy', () => this._removeSource(source), this);
}
}
- _onNotificationShow(_source, notification) {
+ _onNotificationRequestBanner(_source, notification) {
+ // We never display a banner for already acknowledged notifications
+ if (notification.acknowledged)
+ return;
+
+ if (notification.urgency === Urgency.LOW)
+ return;
+
+ if (!notification.source.policy.showBanners && notification.urgency !== Urgency.CRITICAL)
+ return;
+
if (this._notification === notification) {
// If a notification that is being shown is updated, we update
// how it is shown and extend the time until it auto-hides.
const soundFile = 'sound-file' in hints
? Gio.File.new_for_path(hints['sound-file']) : null;
+ notification.acknowledged = false;
notification.update(summary, body, {
gicon,
bannerMarkup: true,
}
let tracker = Shell.WindowTracker.get_default();
+ // Acknowledge notifications that are resident and their app has the
+ // current focus so that we don't show a banner.
if (notification.resident && this.app && tracker.focus_app === this.app)
- this.pushNotification(notification);
- else
- this.showNotification(notification);
+ notification.acknowledged = true;
+
+ this.addNotification(notification);
}
open() {
const GtkNotificationDaemonNotification = GObject.registerClass(
class GtkNotificationDaemonNotification extends MessageTray.Notification {
- _init(source, notification) {
+ _init(source, id, notification) {
super._init(source);
this._serialized = GLib.Variant.new('a{sv}', notification);
+ this.id = id;
const {
title,
this._notificationPending = false;
}
- _createNotification(params) {
- return new GtkNotificationDaemonNotification(this, params);
- }
-
activateAction(actionId, target) {
const params = target ? GLib.Variant.new('av', [target]) : null;
this._app.activate_action(actionId, params, 0, -1, null).catch(error => {
logError(error, `Failed to activate action for ${this._appId}`);
});
+
Main.overview.hide();
Main.panel.closeCalendar();
}
Main.panel.closeCalendar();
}
- addNotification(notificationId, notificationParams, showBanner) {
+ addNotification(notification) {
this._notificationPending = true;
- if (this._notifications[notificationId])
- this._notifications[notificationId].destroy(MessageTray.NotificationDestroyedReason.REPLACED);
+ this._notifications[notification.id]?.destroy(
+ MessageTray.NotificationDestroyedReason.REPLACED);
- let notification = this._createNotification(notificationParams);
notification.connect('destroy', () => {
- delete this._notifications[notificationId];
+ delete this._notifications[notification.id];
});
- this._notifications[notificationId] = notification;
+ this._notifications[notification.id] = notification;
- if (showBanner)
- this.showNotification(notification);
- else
- this.pushNotification(notification);
+ super.addNotification(notification);
this._notificationPending = false;
}
throw e;
}
- notifications.forEach(([notificationId, notification]) => {
- source.addNotification(notificationId, notification.deepUnpack(), false);
+ notifications.forEach(([notificationId, notificationPacked]) => {
+ const notification = new GtkNotificationDaemonNotification(source,
+ notificationId,
+ notificationPacked.deepUnpack());
+ // Acknowledge all stored notification so that we don't show a banner again
+ notification.acknowledged = true;
+ source.addNotification(notification);
});
});
}
}
AddNotificationAsync(params, invocation) {
- let [appId, notificationId, notification] = params;
+ let [appId, notificationId, notificationSerialized] = params;
let source;
try {
}
let timestamp = GLib.DateTime.new_now_local().to_unix();
- notification['timestamp'] = new GLib.Variant('x', timestamp);
+ notificationSerialized['timestamp'] = new GLib.Variant('x', timestamp);
- source.addNotification(notificationId, notification, true);
+ const notification = new GtkNotificationDaemonNotification(source,
+ notificationId,
+ notificationSerialized);
+ source.addNotification(notification);
invocation.return_value(null);
}
if (undoCallback)
this._notification.addAction(_('Undo'), () => undoCallback());
- source.showNotification(this._notification);
+ source.addNotification(this._notification);
}
}
}
Main.messageTray.add(source);
- source.showNotification(notification);
+ source.addNotification(notification);
}
get screencast_in_progress() {
notification.setTransient(true);
Main.messageTray.add(source);
- source.showNotification(notification);
+ source.addNotification(notification);
return file;
}
this._notification.setTransient(true);
this._notification.iconName = 'media-removable-symbolic';
this._notification.connect('destroy', () => delete this._notification);
- source.showNotification(this._notification);
+ source.addNotification(this._notification);
}
_showUnmountNotificationDone(message) {
this._notification.connect('destroy',
() => (this._notification = null));
- source.showNotification(this._notification);
+ source.addNotification(this._notification);
}
_syncMainConnection() {
const app = Shell.AppSystem.get_default().lookup_app('gnome-thunderbolt-panel.desktop');
app?.activate();
});
- source.showNotification(this._notification);
+ source.addNotification(this._notification);
}
/* Session callbacks */
});
notification.setForFeedback(true);
- source.showNotification(notification);
+ source.addNotification(notification);
window.connectObject('notify::title', () => {
[title, banner] = this._getTitleAndBanner(app, window);
const source = new MessageTray.getSystemSource();
Scripting.scriptEvent('notificationShowStart');
- source.connect('notification-show',
+ source.connect('notification-request-banner',
() => Scripting.scriptEvent('notificationShowDone'));
const notification = new MessageTray.Notification(source,
'A test notification');
- source.showNotification(notification);
+ source.addNotification(notification);
await Scripting.sleep(400);
console.debug('Show date menu');